package com.google.code.sapwcrawler.datahandler;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.code.sapwcrawler.data.DownloadedData;
import com.google.code.sapwcrawler.data.Link;
import com.google.code.sapwcrawler.data.ParsedHtml;

public class HtmlParser
{
	static private Logger logger = Logger.getLogger("HtmlParser");
	static private Pattern pHref	= Pattern.compile("href=[\"'](.+?)[\"']",Pattern.CASE_INSENSITIVE);
	static private Pattern pRel		= Pattern.compile("rel=[\"'](.+?)[\"']",Pattern.CASE_INSENSITIVE);
	
	public ParsedHtml parse(DownloadedData data) throws Exception
	{
		if(!data.getContentType().startsWith("text/html"))
			throw new Exception("Not a text/html");
		
		String html = data.toHtml();
		String title = parseTitle(html);
		List<Link> links = parseLinks(html,data.getFrom());
		return new ParsedHtml(data,title,links);
	}
	
	static private Pattern pTitle = Pattern.compile("<title>(.+?)</tltle>",Pattern.CASE_INSENSITIVE);
	
	private String parseTitle(String html)
	{
		Matcher m = pTitle.matcher(html);
		if(m.find())
			return m.group(1).trim();
		return null;
	}
	
	static private Pattern pLink = Pattern.compile("<a(.+?)>(.+)</a>",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
	
	private List<Link> parseLinks(String html,URL url)
	{
		Matcher m = pLink.matcher(html);
		List<Link> list = new ArrayList<Link>();
		while(m.find())
		{
			try
			{
				list.add(parseLink(m,url));
			}
			catch(MalformedURLException e)
			{
				logger.log(Level.INFO,e.toString());
			}
		}
		return list;
	}
	
	private Link parseLink(Matcher data,URL url) throws MalformedURLException
	{
		String title 	= data.group(2).trim();
		String metadata = data.group(1).trim();
		URL href = null;
		String rel = null;
		Matcher hrefMatcher = pHref.matcher(metadata);
		Matcher relMatcher	= pRel.matcher(metadata);
		if(hrefMatcher.find())
			href = normalizeUrl(hrefMatcher.group(1).trim(),url);
		if(relMatcher.find())
			rel = relMatcher.group(1).trim();
		
		return new Link(title,href,rel);
	}
	
	private URL normalizeUrl(String href,URL url) throws MalformedURLException
	{
		if(href.startsWith("javascript:"))
			return null;
		if(href.contains("#"))
			href = href.substring(0,href.indexOf('#'));
		if(href.startsWith("/"))
			return new URL(url.getProtocol() + "://" + url.getHost() + href);
		if(href.startsWith("?"))
			return new URL(file(url) + href);
		if(href.toLowerCase().startsWith("[a-z]+?://"))
			return new URL(href);
		
		return new URL(dir(url) + href);
	}
	
	private String file(URL url)
	{
		String surl = url.toString();
		if(surl.contains("?"))
			return surl.substring(0,surl.indexOf('?'));
		return surl;
	}
	
	private String dir(URL url)
	{
		String surl = url.toString();
		return surl.substring(0,surl.lastIndexOf('/') + 1);
	}
}
